package com.wmb.annotation.handler;

import com.wmb.annotation.annotation.ParamModel;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * @author wulijin
 */
public class UnderlineToCamelArgumentResolver implements HandlerMethodArgumentResolver {

    private static Pattern reg = Pattern.compile("_(\\w)");

    private static String underLineToCamel(String source) {
        Matcher matcher = reg.matcher(source);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }


    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(ParamModel.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
        return handleParameterNames(parameter, request);
    }

    private Object handleParameterNames(MethodParameter parameter, NativeWebRequest request) {
        Object obj = BeanUtils.instantiateClass(parameter.getParameterType());
        BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
        Iterator<String> paramNames = request.getParameterNames();
        while (paramNames.hasNext()) {
            String paramName = paramNames.next();
            Object o = request.getParameter(paramName);
            try {
                beanWrapper.setPropertyValue(underLineToCamel(paramName), o);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return obj;
    }

}
